package es.ibm.santillana.mdm.entryPreview.catalog;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ibm.json.java.JSONArray;
import com.ibm.json.java.OrderedJSONObject;
import com.ibm.pim.attribute.AttributeInstance;
import com.ibm.pim.catalog.Catalog;
import com.ibm.pim.catalog.CatalogManager;
import com.ibm.pim.catalog.item.Item;
import com.ibm.pim.common.exceptions.PIMInternalException;
import com.ibm.pim.common.exceptions.PIMInvalidOperationException;
import com.ibm.pim.common.exceptions.PIMInvalidPathException;
import com.ibm.pim.common.exceptions.PIMSearchException;
import com.ibm.pim.context.Context;
import com.ibm.pim.context.PIMContextFactory;
import com.ibm.pim.hierarchy.Hierarchy;
import com.ibm.pim.hierarchy.HierarchyManager;
import com.ibm.pim.hierarchy.category.Category;
import com.ibm.pim.lookuptable.LookupTable;
import com.ibm.pim.lookuptable.LookupTableEntry;
import com.ibm.pim.lookuptable.LookupTableManager;
import com.ibm.pim.search.SearchQuery;
import com.ibm.pim.search.SearchResultSet;
import com.ibm.pim.spec.SecondarySpec;
import com.ibm.pim.spec.Spec;
import com.ibm.pim.web.framework.dispatcher.AsyncEnabled;
import com.ibm.pim.web.framework.dispatcher.RequestResponseEnabled;

import es.ibm.santillana.mdm.common.util.ConstSantillana;
import es.ibm.santillana.mdm.integration.ChangesHandler;
import es.ibm.santillana.mdm.integration.ExportData;
import es.ibm.santillana.mdm.packs.PackStateTransition;
import es.ibm.santillana.mdm.state.StateManager;

public class CambiarEstadoArticulo implements AsyncEnabled,RequestResponseEnabled{
	
	HttpServletRequest request;
	HttpServletResponse response;
	
	String responseContent ="";

	/* (sin Javadoc) 
	 * @see com.ibm.pim.web.framework.dispatcher.AsyncEnabled#getContentType()
	 */
	public String getContentType() {
		
		return JSON;
	}

	/* (sin Javadoc)
	 * @see com.ibm.pim.web.framework.dispatcher.AsyncEnabled#getResponseContent()
	 */
	public String getResponseContent() {
		
		return responseContent;
	}

	/* (sin Javadoc)
	 * @see com.ibm.pim.web.framework.dispatcher.RequestResponseEnabled#setRequest(javax.servlet.http.HttpServletRequest)
	 */
	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}

	/* (sin Javadoc)
	 * @see com.ibm.pim.web.framework.dispatcher.RequestResponseEnabled#setResponse(javax.servlet.http.HttpServletResponse)
	 */
	public void setResponse(HttpServletResponse response) {
		this.response = response;
	}
	
   private Boolean isPack(Item item, String sSpecName){
		
		try{
			AttributeInstance attInstancePacks =  item.getAttributeInstance(sSpecName + "/Packs");
			if(attInstancePacks!=null){
				List<AttributeInstance> packs = (List<AttributeInstance>) attInstancePacks.getChildren();
				if(packs!=null && packs.size()>0){
					return true;
				}
			}
		}catch(UnsupportedOperationException uoe){
			return false;
		}catch(PIMInvalidPathException pipe){
			return false;
		}catch (PIMInternalException uoe) {
			return false;
		}catch (Exception e) {
			return false;
		}
		return false;
	}
	
	/**
	 * @throws IOException
	 * @throws PIMInvalidOperationException
	 */
	public void obtenerEstados() throws IOException, PIMInvalidOperationException {
		JSONArray aListEstado = new JSONArray();
		
		String pkArticulo = request.getParameter("pkArticulo"); 
		String pkSociedad = request.getParameter("pkSociedad"); 
		
		System.out.println("Obtener estados: pkArt="+pkArticulo+";pkSoc="+pkSociedad);
		
		Context ctx = PIMContextFactory.getCurrentContext();
		HierarchyManager hyMng = ctx.getHierarchyManager();
		CatalogManager ctgMng = ctx.getCatalogManager();
		LookupTableManager lkpMng = ctx.getLookupTableManager();
		
		// Cargar jerarquia Sociedad
		Hierarchy hySociedades = hyMng.getHierarchy(ConstSantillana.JERARQUIA_PAISES);
		
		// Cargar item del catalogo Articulos
		Catalog ctg = ctgMng.getCatalog(ConstSantillana.MAESTRO_ARTICULOS);
		Item itm = ctg.getItemByPrimaryKey(pkArticulo);
		
		// Cargar categoria buscada de la jerarquia Sociedad
		Category catSociedad = hySociedades.getCategoryByPrimaryKey(pkSociedad);

		String sSpecState = null;
		Collection<SecondarySpec> colSpecs = catSociedad.getItemSecondarySpecs();
		Iterator <SecondarySpec> itSpecs = colSpecs.iterator();
		while (itSpecs.hasNext()) {
			SecondarySpec secSpec = itSpecs.next();
			String name = secSpec.getName();
			if (!name.contains("SEARCH")) {
				sSpecState = name;
			}
		}
		sSpecState += "/DESC_Estado";
		
		// Obtener atributos del Item
		System.out.println(sSpecState);
		Item itmEstado = (Item) itm.getAttributeValue(sSpecState);
		String pkItemEstado = itmEstado.getPrimaryKey();
		String desItemEstado = (String)itmEstado.getAttributeValue("Tabla Global/Valor/es_ES");
		System.out.println(itmEstado);
		
		LookupTable lkpTable = lkpMng.getLookupTable("Cambio_Estados");
		LookupTableEntry lkpTableEntry = lkpTable.getLookupTableEntry(pkItemEstado);
		String [] listaDestinos = null;
		if(lkpTableEntry == null) {
			System.out.println("Desde el estado " + desItemEstado + " no se puede realizar un cambio de estado");
		}
		else {
			String destinos = (String) lkpTableEntry.getAttributeValue("CambioEstados/Destino");
			listaDestinos = destinos.split(",");
		}
		
		// Cargar items de los estados del catalogo Estados
		Catalog ctgEstados = ctgMng.getCatalog(ConstSantillana.CATALOGO_ESTADOS);
		for (String destino : listaDestinos) {
			OrderedJSONObject obj = new OrderedJSONObject();
			
			System.out.println(destino);
			Item itmDestino = ctgEstados.getItemByPrimaryKey(destino);
			String desItemDestino = (String)itmDestino.getAttributeValue("Tabla Global/Valor/es_ES");
			System.out.println(desItemDestino);
			
			obj.put("id", itmDestino.getPrimaryKey());
			obj.put("estado", (String)itmDestino.getAttributeValue("Tabla Global/Valor/es_ES"));

			aListEstado.add(obj);
		}
		
		responseContent = aListEstado.serialize(true);	
	}
	
	/**
	 * @throws IOException
	 * @throws PIMInvalidOperationException
	 */
	public void obtenerEstadoActual() throws IOException, PIMInvalidOperationException {
		JSONArray aListEstado = new JSONArray();
		
		String pkArticulo = request.getParameter("pkArticulo"); 
		String pkSociedad = request.getParameter("pkSociedad"); 
		
		System.out.println("Obtener estado actual: pkArt="+pkArticulo+";pkSoc="+pkSociedad);
		
		Context ctx = PIMContextFactory.getCurrentContext();
		HierarchyManager hyMng = ctx.getHierarchyManager();
		CatalogManager ctgMng = ctx.getCatalogManager();
		LookupTableManager lkpMng = ctx.getLookupTableManager();
		
		// Cargar jerarquia Sociedad
		Hierarchy hySociedades = hyMng.getHierarchy(ConstSantillana.JERARQUIA_PAISES);
		
		// Cargar item del catalogo Articulos
		Catalog ctg = ctgMng.getCatalog(ConstSantillana.MAESTRO_ARTICULOS);
		Item itm = ctg.getItemByPrimaryKey(pkArticulo);
		
		// Cargar categoria buscada de la jerarquia Sociedad
		Category catSociedad = hySociedades.getCategoryByPrimaryKey(pkSociedad);

		String sSpecState = null;
		Collection<SecondarySpec> colSpecs = catSociedad.getItemSecondarySpecs();
		Iterator <SecondarySpec> itSpecs = colSpecs.iterator();
		while (itSpecs.hasNext()) {
			SecondarySpec secSpec = itSpecs.next();
			String name = secSpec.getName();
			if (!name.contains("SEARCH")) {
				sSpecState = name;
			}
		}
		sSpecState += "/DESC_Estado";
		
		// Obtener atributos del Item
		System.out.println(sSpecState);
		Item itmEstado = (Item) itm.getAttributeValue(sSpecState);
		String pkItemEstado = itmEstado.getPrimaryKey();
		String desItemEstado = (String)itmEstado.getAttributeValue("Tabla Global/Valor/es_ES");
		System.out.println(itmEstado);
		
		OrderedJSONObject obj = new OrderedJSONObject();
		obj.put("estado", desItemEstado);
		
		aListEstado.add(obj);
		responseContent = aListEstado.serialize(true);
	}
	
	/**
	 * @throws IOException
	 * @throws PIMInvalidOperationException
	 */
	public void cambiarEstado() throws IOException, PIMInvalidOperationException {
		JSONArray aListEstado = new JSONArray();
		
		String pkArticulo = request.getParameter("pkArticulo"); 
		String pkSociedad = request.getParameter("pkSociedad"); 
		String pkEstado = request.getParameter("pkEstado"); 
		
		System.out.println("Cambiar estado: pkArt="+pkArticulo+";Estado="+pkEstado);
		
		Context ctx = PIMContextFactory.getCurrentContext();
		HierarchyManager hyMng = ctx.getHierarchyManager();
		CatalogManager ctgMng = ctx.getCatalogManager();
		
		// Cargar item del catalogo Articulos
		Catalog ctgArticulos = ctgMng.getCatalog(ConstSantillana.MAESTRO_ARTICULOS);
		Item itm = ctgArticulos.getItemByPrimaryKey(pkArticulo);
		
		Catalog ctgEstados = ctgMng.getCatalog(ConstSantillana.CATALOGO_ESTADOS);
		Item itmEstado = ctgEstados.getItemByPrimaryKey(pkEstado);
		
		Hierarchy hySociedades = hyMng.getHierarchy(ConstSantillana.JERARQUIA_PAISES);
		Hierarchy hySociedadTipo = hyMng.getHierarchy(ConstSantillana.JERARQUIA_SOCIEDADES);
		Category catSociedad = hySociedades.getCategoryByPrimaryKey(pkSociedad);

		String sSpecState = null;
		Collection<SecondarySpec> colSpecs = catSociedad.getItemSecondarySpecs();
		Iterator <SecondarySpec> itSpecs = colSpecs.iterator();
		while (itSpecs.hasNext()) {
			SecondarySpec secSpec = itSpecs.next();
			String name = secSpec.getName();
			if (!name.contains("SEARCH")) {
				sSpecState = name;
			}
		}
		
		Category catZGE0 = hySociedadTipo.getCategoryByPrimaryKey(pkSociedad + "ZGE0");
		Category catSTER = hySociedadTipo.getCategoryByPrimaryKey(pkSociedad + "STER");
		
		
//		//Ahora cojo los specs (solo hay uno en esas categorias)
//		
		Spec specZGE0 = catZGE0.getItemSecondarySpecs().iterator().next();
		Spec specSTER = catSTER.getItemSecondarySpecs().iterator().next();
		
		boolean bFormaPack = false;
		String[] aSpecs = new String[2];
		aSpecs[0] = specZGE0.getName();
		aSpecs[1] = specSTER.getName();
		//si el estado que quiero poner es cancelado tengo que comprobar si forma parte de algun pack
		if (pkEstado.equals(ConstSantillana.ESTADO_CANCELADO)) {
			
			
			ArrayList <Item> items = new ArrayList<Item>();
			
			
			String sQueryZGE0 = "select item from catalog('Articulos') "+ 
	                "where item['" + specZGE0.getName() + "/Packs/Articulo_Pack'].pk = '"+pkArticulo+"'"; 
			
			System.out.println(sQueryZGE0);
			SearchQuery searchQZGE0 = ctx.createSearchQuery(sQueryZGE0);
			SearchResultSet resSetZGE0 = searchQZGE0.execute();
			System.out.println("Despues de la query");
			System.out.println("Despues de la query: " + resSetZGE0.size());
			while(resSetZGE0.next()){
				try {
					
					items.add(resSetZGE0.getItem(1));
					System.out.println(resSetZGE0.getItem(1).getPrimaryKey());
				} catch (PIMSearchException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			
			String sQuerySTER = "select item from catalog('Articulos') "+ 
	                "where item['"+ specSTER.getName() + "/Packs/Articulo_Pack'].pk = '"+pkArticulo+"'";
			
			System.out.println(sQuerySTER);
			SearchQuery searchQSTER = ctx.createSearchQuery(sQuerySTER);
			SearchResultSet resSetSTER = searchQSTER.execute();
			System.out.println("Despues de la query");
			System.out.println("Despues de la query: " + resSetSTER.size());
			while(resSetSTER.next()){
				try {
					
					items.add(resSetSTER.getItem(1));
					System.out.println(resSetSTER.getItem(1).getPrimaryKey());
				} catch (PIMSearchException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (items.size() > 0) {
				bFormaPack = true;
			}
		}
		
		
		
		if (!bFormaPack) {
			
			System.out.println("jijiji");
			StateManager.setState(itm, pkEstado, sSpecState);
			ChangesHandler changesAdded = new ChangesHandler(ctgArticulos.getItemByPrimaryKey(itm.getPrimaryKey()),itm,"Articulos", itm.getPrimaryKey(), ctx);			
			changesAdded.createChanges();
			
			
			boolean bPack = false;
			for (int k = 0; k < aSpecs.length; k++){
				String sSpecName = aSpecs[k];
				bPack = isPack(itm, sSpecName);
				if (bPack){
					PackStateTransition pst = new PackStateTransition();
					pst.packStateManage(itm, sSpecName);
				}
			}
			
			itm.save();
			try {
				ExportData exportData = new ExportData();
				exportData.exportXML(changesAdded.getIntegrationChanges());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}			
			
			OrderedJSONObject obj = new OrderedJSONObject();
			obj.put("mensaje", "EstadoCambiado");
			
			aListEstado.add(obj);
			responseContent = aListEstado.serialize(true);
		}
		else {
			OrderedJSONObject obj = new OrderedJSONObject();
			obj.put("mensaje", "ReferenciaEnPack");
			
			aListEstado.add(obj);
			responseContent = aListEstado.serialize(true);
		}
		
	}
	
}
